##
#   Project: BlueDUN
#            Internet connection manager for bluetooth devices.
#    Author: Fabio Castelli <muflone@vbsimple.net>
# Copyright: 2009 Fabio Castelli
#   License: GPL-2+
#  This program is free software; you can redistribute it and/or modify it
#  under the terms of the GNU General Public License as published by the Free
#  Software Foundation; either version 2 of the License, or (at your option)
#  any later version.
# 
#  This program is distributed in the hope that it will be useful, but WITHOUT
#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
#  more details.
# 
# On Debian GNU/Linux systems, the full text of the GNU General Public License
# can be found in the file /usr/share/common-licenses/GPL-2.
##

import gtk
import gtk.glade
import subprocess
import devices
import handlepaths
import gettext
from gettext import gettext as _

# Load domain for translation
for module in (gettext, gtk.glade):
  module.bindtextdomain(handlepaths.APP_NAME, handlepaths.getPath('locale'))
  module.textdomain(handlepaths.APP_NAME)

modelPorts = gtk.ListStore(int, str, str, int)
tvwPorts = None
btnReleasePort = None

COL_PORTNR, COL_PORTNAME, COL_ADDRESS, COL_CHANNEL = range(4)

def on_btnRefreshPorts_clicked(widget, data=None):
  "List all rfcomm ports"
  modelPorts.clear()
  proc = subprocess.Popen(['rfcomm', '-a'], stdout=subprocess.PIPE)
  lines = proc.communicate()[0].split('\n')
  for line in lines:
    if len(line) > 1:
      port, info = line.split(':', 1)
      info = info[1:].split(' ')
      modelPorts.append([int(port[6:]), port, info[0], int(info[2])])

def on_btnBindPort_clicked(widget, data=None):
  "Bind a new rfcomm port using the previously selected address and channel"
  address, portDUN = devices.showWindow()
  if address and portDUN:
    # Search next first free rfcomm port
    nextPort = 0
    while len([port for port in modelPorts if port[COL_PORTNR] == nextPort]) > 0:
      nextPort += 1
    # Add a new port
    cmd = ['gksudo', 'rfcomm', 'bind', str(nextPort), address, str(portDUN)]
    print 'bind new rfcomm port: %s' % ' '.join(cmd)
    proc = subprocess.Popen(cmd)
    proc.communicate()
    on_btnRefreshPorts_clicked(widget, data)

def on_btnReleasePort_clicked(widget, data=None):
  "Release the selected port"
  iter = tvwPorts.get_selection().get_selected()[1]
  if iter:
    cmd = ['gksudo', 'rfcomm', 'release', str(modelPorts[iter][COL_PORTNR])]
    print 'release rfcomm port: %s' % ' '.join(cmd)
    proc = subprocess.Popen(cmd)
    proc.communicate()
    on_btnRefreshPorts_clicked(widget, data)

def on_tvwPorts_selection_changed(selection): 
  "Control sensitiveness of the buttons if items are selected"
  model, paths = selection.get_selected_rows()
  btnReleasePort.set_sensitive(len(paths) > 0)

def showWindow():
  "Show rfcomm ports dialog"
  global tvwPorts
  global btnReleasePort
  
  gladeFile = gtk.glade.XML(
    fname=handlepaths.getPath('ui', 'rfcomms.glade'),
    domain=handlepaths.APP_NAME)
  signals = {
    'on_btnRefreshPorts_clicked': on_btnRefreshPorts_clicked,
    'on_btnBindPort_clicked': on_btnBindPort_clicked,
    'on_btnReleasePort_clicked': on_btnReleasePort_clicked
  }
  gladeFile.signal_autoconnect(signals)
  gw = gladeFile.get_widget
  # Ports window
  dialogPorts = gw('dialogPorts')
  dialogPorts.set_icon_from_file(handlepaths.get_app_logo())
  dialogPorts.set_title(_('RFCOMM ports'))
  btnReleasePort = gw('btnReleasePort')

  tvwPorts = gw('tvwPorts')
  tvwPorts.set_model(modelPorts)
  tvwPorts.get_selection().connect('changed', on_tvwPorts_selection_changed)
  
  # Column for port name
  cell = gtk.CellRendererText()
  column = gtk.TreeViewColumn(_('Port name'))
  column.set_resizable(True)
  column.set_expand(True)
  column.pack_start(cell)
  column.set_attributes(cell, text=1)
  tvwPorts.append_column(column)

  # Column for address
  cell = gtk.CellRendererText()
  column = gtk.TreeViewColumn(_('Bluetooth address'))
  column.set_resizable(True)
  column.set_expand(True)
  column.pack_start(cell)
  column.set_attributes(cell, text=2)
  tvwPorts.append_column(column)

  # Column for channel
  cell = gtk.CellRendererText()
  cell.set_property('xalign', 0.5)
  column = gtk.TreeViewColumn(_('Channel'))
  column.set_resizable(True)
  column.pack_start(cell)
  column.set_attributes(cell, text=3)
  tvwPorts.append_column(column)

  on_btnRefreshPorts_clicked(None)
  dialogPorts.run()
  dialogPorts.destroy()
